package jmine.tec.di.injector.impl;

import java.lang.reflect.Field;

import jmine.tec.annotations.Unmodifiable;
import jmine.tec.di.injector.Injector;
import jmine.tec.di.metadata.DependencyMetaData;
import jmine.tec.di.scope.TypedScope;
import jmine.tec.di.type.TypeConvertionException;

/**
 * Injeta dependencias atraves de um campo.
 * 
 * @author MarceloT
 */
@Unmodifiable
public class FieldBasedInjector implements Injector {

    private final Field field;

    private DependencyMetaData meta;

    /**
     * @param meta o resolver
     * @param field o campo
     */
    public FieldBasedInjector(Field field, DependencyMetaData meta) {
        super();
        this.field = field;
        field.setAccessible(true);
        this.meta = meta;
    }

    /**
     * Faz 'wrap' das excecoes para {@link IllegalStateException}
     * 
     * @param target o alvo a ter uma dependencia injetada
     * @param properties as propriedades de onde resolver as dependencias
     * @throws TypeConvertionException e
     */
    public void doInject(Object target, TypedScope properties) throws TypeConvertionException {
        try {
            this.field.set(target, this.meta.resolveObjectWrap(properties));
        } catch (IllegalAccessException e) {
            throw new IllegalStateException(e);
        }
    }

    /**
     * @return {@link DependencyMetaData}
     */
    public DependencyMetaData getDependencyMetaData() {
        return this.meta;
    }
}
